/*
 * Copyright (c) 2010-2011, Yawning <yawninglol at gmail.com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   * Neither the name of the Mew Developers nor the
 *     names of its contributors may be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

package yawning.mew.pivot.feraldruid;

import org.apache.pivot.beans.BXML;
import org.apache.pivot.beans.BXMLSerializer;
import org.apache.pivot.collections.HashMap;
import org.apache.pivot.collections.List;
import org.apache.pivot.collections.Map;
import org.apache.pivot.json.JSON;
import org.apache.pivot.serialization.SerializationException;
import org.apache.pivot.wtk.Component;
import org.apache.pivot.wtk.TableView;
import org.apache.pivot.wtk.Spinner;

import yawning.mew.character.Clazz;
import yawning.mew.character.Glyph;
import yawning.mew.character.Talent;
import yawning.mew.character.Toon;
import yawning.mew.pivot.MewPivotTalentBase;
import yawning.mew.pivot.MewTableViewMouseButtonListener;

import java.io.IOException;
import java.util.Properties;

/**
 * Mew Pivot Feral Druid Talent/Glyph specific UI components.
 *
 * @author Yawning <yawninglol at gmail.com>
 */
public class Talents extends MewPivotTalentBase {
	private Component mComponent;

	@BXML private TableView glyphTable = null;

	// Common talents
	@BXML private Spinner talentFeralSwiftness;
	@BXML private Spinner talentFuror;
	@BXML private Spinner talentFurySwipes;
	@BXML private Spinner talentPrimalFury;
	@BXML private Spinner talentFeralAggression;
	@BXML private Spinner talentFeralCharge;
	@BXML private Spinner talentStampede;
	@BXML private Spinner talentLeaderOfThePack;
	@BXML private Spinner talentEndlessCarnage;
	@BXML private Spinner talentRendAndTear;
	@BXML private Spinner talentBerserk;
	@BXML private Spinner talentHeartOfTheWild;
	@BXML private Spinner talentMasterShapeshifter;

	// DPS talents
	@BXML private Spinner talentPredatoryStrikes;
	@BXML private Spinner talentKingOfTheJungle;
	@BXML private Spinner talentPrimalMadness;
	@BXML private Spinner talentBloodInTheWater;

	// Tank talents
	@BXML private Spinner talentInfectedWounds;
	@BXML private Spinner talentThickHide;
	@BXML private Spinner talentSurvivalInstincts;
	@BXML private Spinner talentNaturalReaction;
	@BXML private Spinner talentPulverize;
	@BXML private Spinner talentPerseverance;

	// TODO: Tank/Utility talents, not that they're visible anyway.
	@BXML private Spinner talentBrutalImpact;

	public Talents() {
		BXMLSerializer bxmlSerializer = new BXMLSerializer();

		try {
			mComponent = (Component) bxmlSerializer.readObject(getClass().getResource("Talents.bxml"));
		} catch (IOException e) {
			e.printStackTrace();
		} catch (SerializationException e) {
			e.printStackTrace();
		}

		bxmlSerializer.bind(this);

		glyphTable.getComponentMouseButtonListeners().add(new MewTableViewMouseButtonListener());
	}

	public Component getComponent() {
		return mComponent;
	}

	@SuppressWarnings("unchecked")
	public void onLoad(Map<String,Object> backingStore) {
		Map<String,?> tmp;

		tmp = JSON.get(backingStore, "talents");

		if (tmp.containsKey("Talent.Furor")) { talentFuror.setSelectedIndex((Integer) tmp.get("Talent.Furor")); }
		if (tmp.containsKey("Talent.FeralSwiftness")) { talentFeralSwiftness.setSelectedIndex((Integer) tmp.get("Talent.FeralSwiftness")); }
		if (tmp.containsKey("Talent.FurySwipes")) { talentFurySwipes.setSelectedIndex((Integer) tmp.get("Talent.FurySwipes")); }
		if (tmp.containsKey("Talent.PrimalFury")) { talentPrimalFury.setSelectedIndex((Integer) tmp.get("Talent.PrimalFury")); }
		if (tmp.containsKey("Talent.FeralAggression")) { talentFeralAggression.setSelectedIndex((Integer) tmp.get("Talent.FeralAggression")); }
		if (tmp.containsKey("Talent.FeralCharge")) { talentFeralCharge.setSelectedIndex((Integer) tmp.get("Talent.FeralCharge")); }
		if (tmp.containsKey("Talent.Stampede")) { talentStampede.setSelectedIndex((Integer) tmp.get("Talent.Stampede")); }
		if (tmp.containsKey("Talent.LeaderOfThePack")) { talentLeaderOfThePack.setSelectedIndex((Integer) tmp.get("Talent.LeaderOfThePack")); }
		if (tmp.containsKey("Talent.EndlessCarnage")) { talentEndlessCarnage.setSelectedIndex((Integer) tmp.get("Talent.EndlessCarnage")); }
		if (tmp.containsKey("Talent.RendAndTear")) { talentRendAndTear.setSelectedIndex((Integer) tmp.get("Talent.RendAndTear")); }
		if (tmp.containsKey("Talent.Berserk")) { talentBerserk.setSelectedIndex((Integer) tmp.get("Talent.Berserk")); }
		if (tmp.containsKey("Talent.HeartOfTheWild")) { talentHeartOfTheWild.setSelectedIndex((Integer) tmp.get("Talent.HeartOfTheWild")); }
		if (tmp.containsKey("Talent.MasterShapeshifter")) { talentMasterShapeshifter.setSelectedIndex((Integer) tmp.get("Talent.MasterShapeshifter")); }

		if (tmp.containsKey("Talent.PredatoryStrikes")) { talentPredatoryStrikes.setSelectedIndex((Integer) tmp.get("Talent.PredatoryStrikes")); }
		if (tmp.containsKey("Talent.KingOfTheJungle")) { talentKingOfTheJungle.setSelectedIndex((Integer) tmp.get("Talent.KingOfTheJungle")); }
		if (tmp.containsKey("Talent.PrimalMadness")) { talentPrimalMadness.setSelectedIndex((Integer) tmp.get("Talent.PrimalMadness")); }
		if (tmp.containsKey("Talent.BloodInTheWater")) { talentBloodInTheWater.setSelectedIndex((Integer) tmp.get("Talent.BloodInTheWater")); }

		if (tmp.containsKey("Talent.InfectedWounds")) { talentInfectedWounds.setSelectedIndex((Integer) tmp.get("Talent.InfectedWounds")); }
		if (tmp.containsKey("Talent.ThickHide")) { talentThickHide.setSelectedIndex((Integer) tmp.get("Talent.ThickHide")); }
		if (tmp.containsKey("Talent.SurvivalInstincts")) { talentSurvivalInstincts.setSelectedIndex((Integer) tmp.get("Talent.SurvivalInstincts")); }
		if (tmp.containsKey("Talent.NaturalReaction")) { talentNaturalReaction.setSelectedIndex((Integer) tmp.get("Talent.NaturalReaction")); }
		if (tmp.containsKey("Talent.Pulverize")) { talentPulverize.setSelectedIndex((Integer) tmp.get("Talent.Pulverize")); }
		if (tmp.containsKey("Talent.Perseverance")) { talentPerseverance.setSelectedIndex((Integer) tmp.get("Talent.Perseverance")); }

		if (tmp.containsKey("Talent.BrutalImpact")) { talentBrutalImpact.setSelectedIndex((Integer) tmp.get("Talent.BrutalImpact")); }

		tmp = JSON.get(backingStore, "glyphs");
		if (tmp != null) {
			for (Map<String,Object> row : (List<Map<String,Object>>) glyphTable.getTableData()) {
				String key = JSON.get(row, "prop");

				if (tmp.containsKey(key)) {
					boolean enabled = (Boolean) tmp.get(key);
					JSON.put(row, "enabled", enabled);
				} else if (row.containsKey("oldProp")) {
					key = JSON.get(row, "oldProp");

					if (tmp.containsKey(key)) {
						boolean enabled = (Boolean) tmp.get(key);
						JSON.put(row,"enabled", enabled);
					}
				}
			}
		}
	}

	@SuppressWarnings("unchecked")
	public void onSave(Map<String,Object> backingStore) {
		HashMap<String,Object> tmp;

		tmp = new HashMap<String,Object>();
		tmp.put("Talent.Furor", (Integer) talentFuror.getSelectedIndex());
		tmp.put("Talent.FeralSwiftness", (Integer) talentFeralSwiftness.getSelectedIndex());
		tmp.put("Talent.FurySwipes", (Integer) talentFurySwipes.getSelectedIndex());
		tmp.put("Talent.PrimalFury", (Integer) talentPrimalFury.getSelectedIndex());
		tmp.put("Talent.FeralAggression", (Integer) talentFeralAggression.getSelectedIndex());
		tmp.put("Talent.FeralCharge", (Integer) talentFeralCharge.getSelectedIndex());
		tmp.put("Talent.Stampede", (Integer) talentStampede.getSelectedIndex());
		tmp.put("Talent.LeaderOfThePack", (Integer) talentLeaderOfThePack.getSelectedIndex());
		tmp.put("Talent.EndlessCarnage", (Integer) talentEndlessCarnage.getSelectedIndex());
		tmp.put("Talent.RendAndTear", (Integer) talentRendAndTear.getSelectedIndex());
		tmp.put("Talent.Berserk", (Integer) talentBerserk.getSelectedIndex());
		tmp.put("Talent.HeartOfTheWild", (Integer) talentHeartOfTheWild.getSelectedIndex());
		tmp.put("Talent.MasterShapeshifter", (Integer) talentMasterShapeshifter.getSelectedIndex());

		tmp.put("Talent.PredatoryStrikes", (Integer) talentPredatoryStrikes.getSelectedIndex());
		tmp.put("Talent.KingOfTheJungle", (Integer) talentKingOfTheJungle.getSelectedIndex());
		tmp.put("Talent.PrimalMadness", (Integer) talentPrimalMadness.getSelectedIndex());
		tmp.put("Talent.BloodInTheWater", (Integer) talentBloodInTheWater.getSelectedIndex());

		tmp.put("Talent.InfectedWounds", (Integer) talentInfectedWounds.getSelectedIndex());
		tmp.put("Talent.ThickHide", (Integer) talentThickHide.getSelectedIndex());
		tmp.put("Talent.SurvivalInstincts", (Integer) talentSurvivalInstincts.getSelectedIndex());
		tmp.put("Talent.NaturalReaction", (Integer) talentNaturalReaction.getSelectedIndex());
		tmp.put("Talent.Pulverize", (Integer) talentPulverize.getSelectedIndex());
		tmp.put("Talent.Perseverance", (Integer) talentPerseverance.getSelectedIndex());

		tmp.put("Talent.BrutalImpact", (Integer) talentBrutalImpact.getSelectedIndex());
		JSON.put(backingStore, "talents", tmp);

		tmp = new HashMap<String,Object>();
		for (Map<String,Object> row : (List<Map<String,Object>>) glyphTable.getTableData()) {
			String key = JSON.get(row, "prop");
			boolean value = (Boolean) JSON.get(row, "enabled");

			tmp.put(key, value);
		}
		JSON.put(backingStore, "glyphs", tmp);
	}

	@SuppressWarnings("unchecked")
	public Properties toProperties() {
		Properties rval = new Properties();

		// Talents
		rval.setProperty("Talent.Furor", Integer.toString(talentFuror.getSelectedIndex()));
		rval.setProperty("Talent.Feral Swiftness", Integer.toString(talentFeralSwiftness.getSelectedIndex()));
		rval.setProperty("Talent.Fury Swipes", Integer.toString(talentFurySwipes.getSelectedIndex()));
		rval.setProperty("Talent.Primal Fury", Integer.toString(talentPrimalFury.getSelectedIndex()));
		rval.setProperty("Talent.Feral Aggression", Integer.toString(talentFeralAggression.getSelectedIndex()));
		rval.setProperty("Talent.Feral Charge", Integer.toString(talentFeralCharge.getSelectedIndex()));
		rval.setProperty("Talent.Stampede", Integer.toString(talentStampede.getSelectedIndex()));
		rval.setProperty("Talent.Leader of the Pack", Integer.toString(talentLeaderOfThePack.getSelectedIndex()));
		rval.setProperty("Talent.Endless Carnage", Integer.toString(talentEndlessCarnage.getSelectedIndex()));
		rval.setProperty("Talent.Rend and Tear", Integer.toString(talentRendAndTear.getSelectedIndex()));
		rval.setProperty("Talent.Berserk", Integer.toString(talentBerserk.getSelectedIndex()));
		rval.setProperty("Talent.Heart of the Wild", Integer.toString(talentHeartOfTheWild.getSelectedIndex()));
		rval.setProperty("Talent.Master Shapeshifter", Integer.toString(talentMasterShapeshifter.getSelectedIndex()));

		rval.setProperty("Talent.Predatory Strikes", Integer.toString(talentPredatoryStrikes.getSelectedIndex()));
		rval.setProperty("Talent.King of the Jungle", Integer.toString(talentKingOfTheJungle.getSelectedIndex()));
		rval.setProperty("Talent.Primal Madness", Integer.toString(talentPrimalMadness.getSelectedIndex()));
		rval.setProperty("Talent.Blood in the Water", Integer.toString(talentBloodInTheWater.getSelectedIndex()));

		rval.setProperty("Talent.Infected Wounds", Integer.toString(talentInfectedWounds.getSelectedIndex()));
		rval.setProperty("Talent.Thick Hide", Integer.toString(talentThickHide.getSelectedIndex()));
		rval.setProperty("Talent.Survival Instincts", Integer.toString(talentSurvivalInstincts.getSelectedIndex()));
		rval.setProperty("Talent.Natural Reaction", Integer.toString(talentNaturalReaction.getSelectedIndex()));
		rval.setProperty("Talent.Pulverize", Integer.toString(talentPulverize.getSelectedIndex()));
		rval.setProperty("Talent.Perseverance", Integer.toString(talentPerseverance.getSelectedIndex()));

		rval.setProperty("Talent.Brutal Impact", Integer.toString(talentBrutalImpact.getSelectedIndex()));

		// Glyphs
		for (Map<String,Object> row : (List<Map<String,Object>>) glyphTable.getTableData()) {
			String key = JSON.get(row, "name");
			boolean value = (Boolean) JSON.get(row, "enabled");

			rval.setProperty(key, Boolean.toString(value));
		}

		// TalentSpec should be "Feral Combat" by default.
		rval.setProperty("TalentSpec", "Feral Combat");

		return rval;
	}

	@SuppressWarnings("unchecked")
	public void onImport(Toon toon) {
		// Import talents.
		Clazz c = Clazz.DRUID;
		talentFuror.setSelectedIndex(toon.getTalent(Talent.getByName(c, "Furor")));
		talentFeralSwiftness.setSelectedIndex(toon.getTalent(Talent.getByName(c, "Feral Swiftness")));
		talentFurySwipes.setSelectedIndex(toon.getTalent(Talent.getByName(c, "Fury Swipes")));
		talentPrimalFury.setSelectedIndex(toon.getTalent(Talent.getByName(c, "Primal Fury")));
		talentFeralAggression.setSelectedIndex(toon.getTalent(Talent.getByName(c, "Feral Aggression")));
		talentFeralCharge.setSelectedIndex(toon.getTalent(Talent.getByName(c, "Feral Charge")));
		talentStampede.setSelectedIndex(toon.getTalent(Talent.getByName(c, "Stampede")));
		talentLeaderOfThePack.setSelectedIndex(toon.getTalent(Talent.getByName(c, "Leader of the Pack")));
		talentEndlessCarnage.setSelectedIndex(toon.getTalent(Talent.getByName(c, "Endless Carnage")));
		talentRendAndTear.setSelectedIndex(toon.getTalent(Talent.getByName(c, "Rend and Tear")));
		talentBerserk.setSelectedIndex(toon.getTalent(Talent.getByName(c, "Berserk")));
		talentHeartOfTheWild.setSelectedIndex(toon.getTalent(Talent.getByName(c, "Heart of the Wild")));
		talentMasterShapeshifter.setSelectedIndex(toon.getTalent(Talent.getByName(c, "Master Shapeshifter")));

		talentPredatoryStrikes.setSelectedIndex(toon.getTalent(Talent.getByName(c, "Predatory Strikes")));
		talentKingOfTheJungle.setSelectedIndex(toon.getTalent(Talent.getByName(c, "King of the Jungle")));
		talentPrimalMadness.setSelectedIndex(toon.getTalent(Talent.getByName(c, "Primal Madness")));
		talentBloodInTheWater.setSelectedIndex(toon.getTalent(Talent.getByName(c, "Blood in the Water")));

		talentInfectedWounds.setSelectedIndex(toon.getTalent(Talent.getByName(c, "Infected Wounds")));
		talentThickHide.setSelectedIndex(toon.getTalent(Talent.getByName(c, "Thick Hide")));
		talentSurvivalInstincts.setSelectedIndex(toon.getTalent(Talent.getByName(c, "Survival Instincts")));
		talentNaturalReaction.setSelectedIndex(toon.getTalent(Talent.getByName(c, "Natural Reaction")));
		talentPulverize.setSelectedIndex(toon.getTalent(Talent.getByName(c, "Pulverize")));
		talentPerseverance.setSelectedIndex(toon.getTalent(Talent.getByName(c, "Perseverance")));

		talentBrutalImpact.setSelectedIndex(toon.getTalent(Talent.getByName(c, "Brutal Impact")));

		// Handle supported glyphs.
		for (Map<String,Object> row : (List<Map<String,Object>>) glyphTable.getTableData()) {
			int idx = ((List<Map<String,Object>>)glyphTable.getTableData()).indexOf(row);
			if (toon.hasGlyph(Glyph.getByName((String) JSON.get(row, "name")))) {
				JSON.put(row, "enabled", true);
			} else {
				JSON.put(row, "enabled", false);
			}
			((List<Map<String,Object>>)glyphTable.getTableData()).update(idx, row);
		}
	}
}
